#ifndef __Point2_hpp__
#define __Point2_hpp__

#include "Platform.hpp"

namespace ge {

//----------------------------------------------------------------------------//
// Point2< T > 
//----------------------------------------------------------------------------//

GE_PACK template < class T >
class GE_PACKED Point2
{
 public:

     Point2( void ) : x( (T)0 ), y( (T)0 )
     {
     }

     Point2( const T& _xy ) : x( _xy ), y( _xy )
     {
     }

     Point2( const T& _x, const T& _y ) : x( _x ), y( _y )
     {
     }

     Point2( const T _v[2] ) : x( _v[0] ), y( _v[1] )
     {
     }

     Point2( const Point2& _p ) : x( _p.x ), y( _p.y )
     {
     }

     Point2& operator = ( const Point2& _p )
     {
          return Set( _p );    
     }

     Point2& operator = ( const T& _xy )
     {
          return Set( _xy );    
     }

     Point2& Set( const T& _xy )
     {
          x = _xy;
          y = _xy;
          return *this;
     }

     Point2& Set( const T& _x, const T& _y )
     {
          x = _x;
          y = _y;
          return *this;
     }

     Point2& Set( const Point2& _p )
     {
          x = _p.x;
          y = _p.y;
          return *this;
     }

     Point2& FromPtr( const T _v[2] )
     {
          x = _v[0];
          y = _v[1];
          return *this;
     }

     Point2& SetZero( void )
     {
          x = (T)0;
          y = (T)0;
          return *this;
     }

     Point2& SetIdentity( void )
     {
          x = (T)1;
          y = (T)1;
          return *this;
     }

     bool operator == ( const Point2& _p ) const
     {
          return x == _p.x && y == _p.y;
     }

     bool operator < ( const Point2& _p ) const
     {
          return x < _p.x && y < _p.y;
     }

     bool operator <= ( const Point2& _p ) const
     {
          return x <= _p.x && y <= _p.y;
     }

     bool operator != ( const Point2& _p ) const
     {
          return !(*this == _p);
     }

     bool operator > ( const Point2& _p ) const
     {
          return !(*this <= _p);
     }

     bool operator >= ( const Point2& _p ) const
     {
          return !(*this < _p);
     }

     Point2 operator + ( const Point2& _pt ) const
     {
          return Point2( x + _pt.x, y + _pt.y );
     }

     Point2 operator - ( const Point2& _pt ) const
     {
          return Point2( x - _pt.x, y - _pt.y );
     }

 public:

     static const Point2 Zero;
     static const Point2 Identity;

 public:

     union
     {
          struct { T x,y; };
          struct { T w,h; };
          struct { T width,height; };
          T v[2];
     };

} GE_UNPACK;

template < class T > const Point2< T > Point2< T >::Zero( 0, 0 );
template < class T > const Point2< T > Point2< T >::Identity( 1, 1 );

typedef Point2< int > Point2i, Size2i;
typedef Point2< uint > Point2ui, Size2ui;
typedef Point2< float > Point2f, Size2f;


} // namespace ge

#endif//__Point2_hpp__
